﻿using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public partial class Parser
{
    private static readonly SyntaxKinds[] MetadataPropertyValueKinds =
    [
        SyntaxKinds.Integer,
        SyntaxKinds.Double,
        SyntaxKinds.TrueKeywordToken,
        SyntaxKinds.FalseKeywordToken,
        SyntaxKinds.NullKeywordToken,
        SyntaxKinds.String,
        SyntaxKinds.Identifier
    ];


    private static readonly SyntaxKinds[] MetadataLabeledObjectEffectiveElementStartKinds =
    [
        SyntaxKinds.Identifier,
        SyntaxKinds.LeftBracketToken,
        SyntaxKinds.TemplatesKeywordToken,
        SyntaxKinds.StyleKeywordToken,
        SyntaxKinds.LabelStyleKeywordToken,
        SyntaxKinds.String,
        SyntaxKinds.MinusToken
    ];


    private static readonly string[] EffectiveElementTypes =
    [
        "AnalysisBase",
        "AnalysisCategory",
        "AnalysisDerived",
        "AnalysisMaximum",
        "AnalysisMean",
        "AnalysisMinimum",
        "AnalysisSampleVariance",
        "AnalysisStdDev",
        "AnalysisStdErr",
        "AnalysisSubHeading",
        "AnalysisSubTotal",
        "AnalysisSummaryData",
        "AnalysisTotal"
    ];


    /*
     * category ::= category_name
     *     [ "category_label" ]
     *     [ other | multiplier | DK | REF | NA ]
     *     [ Exclusive ]
     *     [ Factor (factor_value) ]
     *	   [ Keycode ("keycode_value") ]
     *     [ Expression ("exp_text") ]
     *     [ ElementType (type_value) ]
     *     [ Fix ]
     *     [ NoFilter ]
     */


    private static readonly SyntaxKinds[] MetadataCategoryEffectiveSuffixToken =
    [
        SyntaxKinds.OtherKeywordToken,
        SyntaxKinds.MultiplierKeywordToken,
        SyntaxKinds.KeycodeKeywordToken,
        SyntaxKinds.ExpressionKeywordToken,
        SyntaxKinds.FactorKeywordToken,
        SyntaxKinds.ElementTypeKeywordToken,
        SyntaxKinds.ExclusiveKeywordToken,
        SyntaxKinds.DontKnowKeywordToken,
        SyntaxKinds.RefuseKeywordToken,
        SyntaxKinds.NoAnswerKeywordToken,
        SyntaxKinds.FixKeywordToken,
        SyntaxKinds.NoFilterKeywordToken
    ];


    private static readonly SyntaxKinds[] MetadataOrderKeywordTokens =
    [
        SyntaxKinds.RotKeywordToken,
        SyntaxKinds.RotateKeywordToken,
        SyntaxKinds.RanKeywordToken,
        SyntaxKinds.RandomizeKeywordToken,
        SyntaxKinds.RevKeywordToken,
        SyntaxKinds.ReverseKeywordToken,
        SyntaxKinds.AscKeywordToken,
        SyntaxKinds.AscendingKeywordToken,
        SyntaxKinds.DescKeywordToken,
        SyntaxKinds.DescendingKeywordToken,
        SyntaxKinds.FixKeywordToken,
        SyntaxKinds.NamespaceKeywordToken
    ];


    private static readonly SyntaxKinds[] MetadataFieldValueBoundKinds =
    [
        SyntaxKinds.Integer,
        SyntaxKinds.Double,
        SyntaxKinds.String,
        SyntaxKinds.MinusToken // 负数
    ];


    private static readonly SyntaxKinds[] MetadataFieldKindTokens =
    [
        SyntaxKinds.LoopKeywordToken,
        SyntaxKinds.TextKeywordToken,
        SyntaxKinds.DateKeywordToken,
        SyntaxKinds.LongKeywordToken,
        SyntaxKinds.DoubleKeywordToken,
        SyntaxKinds.BooleanKeywordToken,
        SyntaxKinds.CategoricalKeywordToken,
        SyntaxKinds.InfoKeywordToken,
        SyntaxKinds.CompoundKeywordToken,
        SyntaxKinds.GridKeywordToken,
        SyntaxKinds.PageKeywordToken,
        SyntaxKinds.BlockKeywordToken,
        SyntaxKinds.DefineKeywordToken,
        SyntaxKinds.DbKeywordToken,
        SyntaxKinds.DefineKeywordToken
    ];


    /*
     * field_name
     * [ "field_label" ]
     * [ [ properties ] ]
     * [ styles and templates ]
     *     categorical
     * [ [ min_categories..max_categories ] ]
     * [ categories ]
     * [ expression ("expression_text"
     *     [, ( derive elements | no derive elements ) ] ) ]
     * [ ( initial answer | default answer ) ({category_name(s)}) ]
     * [ axis ]
     * [ usage-type ]
     * [ helper fields ]
     * [ NoCaseData ]
     * [ unversioned ]
     */


    private static readonly SyntaxKinds[] FieldSuffixKeyword =
    [
        SyntaxKinds.ExpressionKeywordToken,
        SyntaxKinds.InitialAnswerKeywordToken,
        SyntaxKinds.DefaultAnswerKeywordToken,
        SyntaxKinds.AxisKeywordToken,
        SyntaxKinds.UsageTypeKeywordToken,
        SyntaxKinds.HelperFieldsKeywordToken,
        SyntaxKinds.PrecisionKeywordToken,
        SyntaxKinds.ScaleKeywordToken,
        SyntaxKinds.NoCaseDataKeywordToken,
        SyntaxKinds.UnversionedKeywordToken,
        SyntaxKinds.VersionedKeywordToken,
        SyntaxKinds.ValidationKeywordToken,
        SyntaxKinds.CodesKeywordToken,
        SyntaxKinds.RowKeywordToken,
        SyntaxKinds.ColumnKeywordToken,
        SyntaxKinds.ExpandKeywordToken,
        SyntaxKinds.GridKeywordToken
    ];

    /// <summary>
    ///     解析字符串或标识符
    ///     <list type="number">
    ///         <item>如果当前是字符串，将尝试 将其转换为标识符</item>
    ///         <item>如果当前是'-'，返回<see cref="Identifier.Default" /></item>
    ///         <item>如果字符串不是有效的标识符，将报告错误</item>
    ///     </list>
    /// </summary>
    private Identifier ParseMetadataNameIdOrString(bool allowMinus = true)
    {
        SourceNode current = GetCurrentNode();

        if (!current.IsNode(SyntaxKinds.MinusToken))
        {
            return ParseIdentifierLike();
        }

        if (!allowMinus)
        {
            Raise(DiagnosticDescriptors.UnexpectedToken,
                current, $"{IdentifierName} 或 字符串");
        }

        return Identifier.Default;
    }


    private Expression ParseMetadataPropertyValue()
    {
        const string msgArg = "字符串、整数、小数、字符串、布尔值或标识符";

        if (Eof() || !TryParse(MetadataPropertyValueKinds, out SourceNode? node, false, true))
        {
            return CreateEmptyExpression(DiagnosticDescriptors.UnexpectedToken, msgArg);
        }

        return node.Kind switch
        {
            // 整数
            SyntaxKinds.Integer => ParseInteger(),
            // 小数
            SyntaxKinds.Double => ParseDouble(),
            // 布尔值
            SyntaxKinds.TrueKeywordToken or SyntaxKinds.FalseKeywordToken => ParseBoolean(),
            // null
            SyntaxKinds.NullKeywordToken => ParseNull(),
            // string
            SyntaxKinds.String => ParseString(),
            // Identifier
            SyntaxKinds.Identifier => ParseIdentifierName(true),
            _ => CreateEmptyExpression(DiagnosticDescriptors.UnexpectedToken, msgArg)
        };
    }


    /// <summary>
    ///     解析单个元数据属性， PropertyName = PropertyValue，
    ///     此方法从当前节点开始。
    /// </summary>
    private MetadataProperty ParseMetadataProperty()
    {
        Identifier name = ParseIdentifierName(true);
        Expect(SyntaxKinds.EqualToken, true);
        Expression value = ParseMetadataPropertyValue();
        MetadataProperty property = NodeFactory.CreateMetadataProperty(null, name, value);
        return FinishNode(property, GetStartPoint(name));
    }


    /// <summary>
    ///     解析元数的属性列表，以 '[' 开头，以 ']' 结束。
    /// </summary>
    /// <remarks>
    ///     需要当前 Token 是 '['
    /// </remarks>
    private MetadataProperties ParseMetadataProperties(Identifier? areaName)
    {
        SyntaxPoint start = GetStartPoint(areaName as ITextRange ?? GetCurrentReportNode());
        List<MetadataProperty> properties = new();

        ParseBlockWithSeparator(
            [SyntaxKinds.RightBracketToken],
            SyntaxKinds.CommaToken,
            ParseMetadataProperty,
            properties.Add,
            false,
            true);

        MetadataProperties metadataProperties = NodeFactory.CreateMetadataProperties(null, areaName, properties);
        return FinishNode(metadataProperties, start);
    }


    /// <summary>
    ///     解析元数据声明脚本中的单个模板配置，类似于 MetadataProperty，
    ///     不同的是，MetadataTemplate 只接受字符串值，在解析模板值时，
    ///     应当将可以转换为字符串的值转换为字符串类型。
    /// </summary>
    private MetadataTemplate ParseMetadataTemplate()
    {
        Identifier name = ParseIdentifierName(true);
        // =
        Expect(SyntaxKinds.EqualToken, true);
        // value
        Expression expr = ParseMetadataPropertyValue();

        MetadataTemplate template = NodeFactory.CreateMetadataTemplate(null,
            name, NodeConverter.ToString(expr, null));

        return FinishNode(template, GetStartPoint(name));
    }


    /// <summary>
    ///     解析元数据脚本中的模板列表声明，需要当前节点是 templates 关键字
    /// </summary>
    private MetadataTemplates ParseMetadataTemplates(Identifier? areaName)
    {
        SyntaxPoint start = GetStartPoint(areaName as ITextNode ?? GetCurrentReportNode());
        // templates
        SyntaxToken keyword = GetToken();
        List<MetadataTemplate> templates = new();
        // (
        Expect(SyntaxKinds.LeftParenthesisToken, true);

        ParseBlockWithSeparator(
            [SyntaxKinds.RightParenthesisToken],
            SyntaxKinds.CommaToken,
            ParseMetadataTemplate,
            templates.Add,
            allowSeparatorNewline: true);

        MetadataTemplates metadataTemplates = NodeFactory.CreateMetadataTemplates(null, keyword, templates);
        return FinishNode(metadataTemplates, start);
    }


    /// <summary>
    ///     解析带描述的元数元素中的文本描述。
    /// </summary>
    /// <remarks>
    ///     &lt;label&gt; ::= ( [ AreaName: ] ( "Label-text" | - ) )*
    /// </remarks>
    private MetadataLabel ParseMetadataLabel(Identifier? areaName)
    {
        SyntaxPoint start = GetCurrentStartPoint();
        MetadataLabel label;
        // string
        if (CurrentIs(SyntaxKinds.String))
        {
            StringLiteral text = ParseString();
            label = NodeFactory.CreateMetadataLabel(null, areaName, text);
        }
        else
        {
            label = NodeFactory.CreateMetadataLabel(null, areaName, null);
        }

        return FinishNode(label, start);
    }


    /// <summary>
    ///     样式属性可能直接赋值单个值，也可能带有一个属性列表。
    ///     <list type="number">
    ///         <item>
    ///             <code>Control = ListBox</code>
    ///         </item>
    ///         <item>
    ///             <code>Control ( Accelerator = "R", Type = ListBox )</code>
    ///         </item>
    ///     </list>
    /// </summary>
    private MetadataStyleProperty ParseMetadataStyleProperty()
    {
        Identifier name = ParseIdentifierName(true);
        // Style
        MetadataStyleProperty style = NodeFactory.CreateMetadataStyleProperty(null, name, EmptyExpression.Default);
        // = | (
        SyntaxToken? token = Expect([SyntaxKinds.EqualToken, SyntaxKinds.LeftParenthesisToken], true);
        // =
        if (token != null && token.IsNode(SyntaxKinds.EqualToken))
        {
            style.Update(ParseMetadataPropertyValue());
        }
        // (
        else if (token != null && token.IsNode(SyntaxKinds.LeftParenthesisToken))
        {
            ParseBlockWithSeparator(
                [SyntaxKinds.RightParenthesisToken],
                SyntaxKinds.CommaToken,
                ParseMetadataProperty,
                p => style.Update(p),
                false,
                true);
        }

        return FinishNode(style, GetStartPoint(name));
    }


    /// <summary>
    ///     解析元数据脚本中的样式配置语法，需要当前节点是 style 关键字
    /// </summary>
    /// <remarks>
    ///     e.g.
    ///     <code>
    ///         Style ( Control ( Accelerator = "R", Type = ListBox ) )
    ///         Style ( Color = "Blue", ElementAlign = Right, Hidden = False )
    ///     </code>
    /// </remarks>
    private MetadataStyle ParseMetadataStyle(Identifier? areaName)
    {
        SyntaxToken styleKeywordToken = GetToken();
        MetadataStyle metadataStyle = NodeFactory.CreateMetadataStyle(null, areaName, styleKeywordToken, null);
        SyntaxToken leftParenthesisToken = Expect(SyntaxKinds.LeftParenthesisToken, true);

        if (!leftParenthesisToken.IsEmpty)
        {
            ParseBlockWithSeparator(
                [SyntaxKinds.RightParenthesisToken],
                SyntaxKinds.CommaToken,
                ParseMetadataStyleProperty,
                metadataStyle.AddArealObject,
                false,
                true);
        }

        return FinishNode(metadataStyle, GetStartPoint(styleKeywordToken));
    }


    /// <summary>
    ///     解析元数据带标签对象的属性、模板、样式等信息，
    ///     此方法最后会停止在文件末尾或者非'['、'style'、'labelStyle'、'ArealName:'、字符串 的位置。
    /// </summary>
    private MetadataLabeledObjectInfo ParseMetadataLabeledInfo()
    {
        List<MetadataProperties> props = new();
        List<MetadataTemplates> temps = new();
        List<MetadataStyle> styles = new();
        List<MetadataStyle> labelStyles = new();
        List<MetadataLabel> labels = new();

        Identifier? areaName = null;

        while (!Eof())
        {
            if (!TryParse(MetadataLabeledObjectEffectiveElementStartKinds, out SourceNode? next,
                    allowNewLine: true))
            {
                break;
            }

            // IdentifierName
            if (next.IsIdentifier)
            {
                Identifier identifierName = ParseIdentifierName(true);
                // [ AreaName: ]
                if (TryParse(SyntaxKinds.ColonToken, allowNewLine: true))
                {
                    areaName = identifierName;
                }
                else
                {
                    break;
                }
            }
            // [
            else if (next.IsNode(SyntaxKinds.LeftBracketToken))
            {
                props.Add(ParseMetadataProperties(areaName));
            }
            // templates
            else if (next.IsNode(SyntaxKinds.TemplatesKeywordToken))
            {
                temps.Add(ParseMetadataTemplates(areaName));
            }
            // style
            else if (next.IsNode(SyntaxKinds.StyleKeywordToken))
            {
                styles.Add(ParseMetadataStyle(areaName));
            }
            // labelStyle
            else if (next.IsNode(SyntaxKinds.LabelStyleKeywordToken))
            {
                labelStyles.Add(ParseMetadataStyle(areaName));
            }
            // "" | -
            else if (next.IsString || next.IsNode(SyntaxKinds.MinusToken))
            {
                if (labels.Exists(lb => lb.AreaName == areaName))
                {
                    Raise(DiagnosticDescriptors.RepetitiveArealLabel, next);
                }
                else
                {
                    labels.Add(ParseMetadataLabel(areaName));
                }
            }
            else
            {
                break;
            }
        }

        return new MetadataLabeledObjectInfo
        {
            Properties = props,
            Templates = temps,
            Styles = styles,
            LabelStyles = labelStyles,
            Labels = labels
        };
    }


    private MetadataArealInfo ParseArealInfo()
    {
        // (
        Next();
        //
        StringLiteral? language = null;
        StringLiteral? userContext = null;
        StringLiteral? labelType = null;

        List<StringLiteral> strList = new();
        ParseBlockWithSeparator(
            [SyntaxKinds.RightParenthesisToken],
            SyntaxKinds.CommaToken,
            () => ParseContinuousTokenAsString(SyntaxKinds.CommaToken, SyntaxKinds.RightParenthesisToken),
            strList.Add,
            false,
            true,
            3);

        if (strList.Count > 0)
        {
            language = strList[0];
        }

        if (strList.Count > 1)
        {
            userContext = strList[1];
        }

        if (strList.Count > 2)
        {
            labelType = strList[2];
        }

        return new MetadataArealInfo(language, userContext, labelType);
    }


    private MetadataLabeledObjectStartInfo StartMetadataLabeledObject()
    {
        // 允许接收字符串或标识符
        Identifier identifierName = ParseMetadataNameIdOrString();

        MetadataLabeledObjectInfo labeledInfo = MetadataLabeledObjectInfo.Empty;
        if (CurrentIs(SyntaxKinds.MinusToken) ||
            !Identifier.IsDefaultOrEmpty(identifierName))
        {
            labeledInfo = ParseMetadataLabeledInfo();
        }

        return new MetadataLabeledObjectStartInfo
        {
            Id = identifierName,
            LabeledObjectInfo = labeledInfo
        };
    }


    /// <summary>
    ///     解析元数据脚本中 lcl 关键字声明的语言、上下文等，
    ///     需要当前节点是lcl关键字<see cref="SyntaxKinds.LclKeywordToken" />
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         AreaName lcl ( [language] [, [user-context] [, [label-type] ]] )
    ///     </code>
    /// </remarks>
    private MetadataArealDeclaration ParseMetadataArealDeclaration(MetadataLabeledObjectStartInfo info)
    {
        // lcl keyword
        SyntaxToken lclKeywordToken = GetToken();
        MetadataArealDeclaration decl = NodeFactory.CreateMetadataArealDeclaration(null, lclKeywordToken, info.Id);
        info.LabeledObjectInfo.UpdateToLabeledObject(decl);
        // (
        SyntaxToken leftParenthesisToken = Expect(SyntaxKinds.LeftParenthesisToken, true);

        if (!leftParenthesisToken.IsEmpty)
        {
            MetadataArealInfo arealInfo = ParseArealInfo();
            decl.Update(arealInfo.Language, arealInfo.UserContext, arealInfo.LabelType);
        }

        return FinishNode(decl, GetStartPoint(info.Id));
    }


    private Expression ParseMetadataFieldValue()
    {
        if (Eof())
        {
            return CreateEmptyExpression(
                DiagnosticDescriptors.UnexpectedToken,
                "字符串、布尔值、数字 或 分类值");
        }

        SourceNode next = Next();

        return next.Kind switch
        {
            // 字符串
            SyntaxKinds.String => ParseString(),
            // 布尔值
            SyntaxKinds.TrueKeywordToken or SyntaxKinds.FalseKeywordToken => ParseBoolean(),
            // 数字
            SyntaxKinds.Integer => ParseInteger(),
            SyntaxKinds.Double => ParseDouble(),
            // 分类值
            SyntaxKinds.LeftCurlyToken => ParseCategorical(),
            // Identifier -> String
            SyntaxKinds.Identifier => NodeConverter.ToString(ParseIdentifierName(true), null),
            // Unexpected
            _ => CreateEmptyExpression(
                DiagnosticDescriptors.UnexpectedToken,
                "字符串、布尔值、数字 或 分类值")
        };
    }

    /// <summary>
    ///     解析元数据字段引用节点，需要当前节点类型是<see cref="SyntaxKinds.UseKeywordToken" />
    /// </summary>
    private MetadataFieldReference ParseMetadataFieldReference()
    {
        SyntaxToken useKeywordToken = GetToken();
        // \\.
        SyntaxToken? backslashBackslashDotToken = null;
        if (TryParse(SyntaxKinds.BackSlashBackSlashDotToken))
        {
            backslashBackslashDotToken = GetToken();
        }

        // Identifier | String
        Identifier fieldName = TryParse(() =>
        {
            Next();
            Identifier name = ParseIdentifierLike();
            return Identifier.IsDefaultOrEmpty(name) ? null : name;
        }) ?? Identifier.Default;

        MetadataFieldReference node = NodeFactory.CreateMetadataFieldReference(null,
            useKeywordToken, fieldName);

        if (backslashBackslashDotToken != null)
        {
            node.Update(backslashBackslashDotToken);
        }

        return FinishNode(node, GetStartPoint(useKeywordToken));
    }

    private void TryParseMetadataFieldOrReference(MetadataFieldReferenceSuffix suffix)
    {
        // (
        if (!TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            return;
        }

        // use
        if (TryParse(SyntaxKinds.UseKeywordToken, allowNewLine: true))
        {
            suffix.Update(ParseMetadataFieldReference());
        }
        // field
        else if (TryParse(IdentifierOrStringKinds, out _, allowNewLine: true))
        {
            suffix.Update(ParseMetadataField());
        }

        // )
        Expect(SyntaxKinds.RightParenthesisToken);
    }


    /// <summary>
    ///     解析元数据 other 后缀，需要当前节点是 other 关键字
    /// </summary>
    /// <returns></returns>
    private MetadataOther ParseMetadataOther()
    {
        SyntaxToken otherKeywordToken = GetToken();
        MetadataOther otherSuffix = NodeFactory.CreateMetadataOther(null, otherKeywordToken);
        TryParseMetadataFieldOrReference(otherSuffix);
        return FinishNode(otherSuffix, GetStartPoint(otherKeywordToken));
    }


    /// <summary>
    ///     解析元数据 multiplier 后缀，需要当前节点是 multiplier 关键字
    /// </summary>
    /// <returns></returns>
    private MetadataMultiplier ParseMetadataMultiplier()
    {
        SyntaxToken multiplierKeywordToken = GetToken();
        MetadataMultiplier multiplierSuffix = NodeFactory.CreateMetadataMultiplier(null, multiplierKeywordToken);
        TryParseMetadataFieldOrReference(multiplierSuffix);
        return FinishNode(multiplierSuffix, GetStartPoint(multiplierKeywordToken));
    }


    /// <summary>
    ///     解析元数据 keycode 后缀。
    /// </summary>
    /// <returns></returns>
    private MetadataKeyCode ParseMetadataKeyCode()
    {
        SyntaxToken keyCodeKeywordToken = GetToken();
        // (
        Expect(SyntaxKinds.LeftParenthesisToken);
        // value
        Expression value = ParseMetadataFieldValue();
        // )
        Expect(SyntaxKinds.RightParenthesisToken);

        MetadataKeyCode keyCode = NodeFactory.CreateMetadataKeyCode(null, keyCodeKeywordToken, null);
        // keycode 将读取到的内容转换为字符串，如果不是字符串并且不是数字或标识符，将报告错误
        if (value.Is<StringLiteral>(SyntaxKinds.String, out StringLiteral? strNode))
        {
            keyCode.Update(strNode);
        }
        else
        {
            // 整数和布尔值可以直接转换成字符串
            if (value.IsOneOfNode(SyntaxKinds.Integer, SyntaxKinds.Boolean))
            {
                keyCode.Update(NodeConverter.ToString(value));
            }
            else
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, value, "字符串");
            }
        }

        return FinishNode(keyCode, GetStartPoint(keyCodeKeywordToken));
    }


    /// <summary>
    ///     解析元数据脚本中 expression 后缀，需要当前节点类型是<see cref="SyntaxKinds.ExpressionKeywordToken" />
    /// </summary>
    /// <returns></returns>
    private MetadataExpression ParseMetadataExpression()
    {
        SyntaxToken expressionKeywordToken = GetToken();

        // (
        Expect(SyntaxKinds.LeftParenthesisToken);
        // expression text
        StringLiteral expression = StringLiteral.Default;
        if (Expect([SyntaxKinds.String]) != null)
        {
            expression = ParseString();
        }

        MetadataExpression expressionNode = NodeFactory.CreateMetadataExpression(null,
            expressionKeywordToken, expression, null);

        //,
        if (TryParse(SyntaxKinds.CommaToken, allowNewLine: true))
        {
            SyntaxToken? featureToken = Expect([
                SyntaxKinds.DeriveElementsKeywordToken, SyntaxKinds.NoDeriveElementsKeywordToken
            ]);

            if (featureToken != null)
            {
                expressionNode.Update(featureToken);
            }
        }

        // )
        Expect(SyntaxKinds.RightParenthesisToken);
        return FinishNode(expressionNode, GetStartPoint(expressionKeywordToken));
    }


    /// <summary>
    ///     解析元数据脚本中的 factor 后缀，需要当前节点是 <see cref="SyntaxKinds.FactorKeywordToken" />
    /// </summary>
    /// <returns></returns>
    private MetadataFactor ParseMetadataFactor()
    {
        SyntaxToken factorKeywordToken = GetToken();

        // (
        Expect(SyntaxKinds.LeftParenthesisToken);
        Expression value = ParseMetadataFieldValue();
        // )
        Expect(SyntaxKinds.RightParenthesisToken);

        MetadataFactor factor = NodeFactory.CreateMetadataFactor(null, factorKeywordToken, value);
        return FinishNode(factor, GetStartPoint(factorKeywordToken));
    }


    /// <summary>
    ///     解析元数据脚本中的 ElementType 后缀，需要当前的节点类型是<see cref="SyntaxKinds.ElementTypeKeywordToken" />
    /// </summary>
    /// <returns></returns>
    private MetadataElementType ParseMetadataElementType()
    {
        SyntaxToken elementTypeKeywordToken = GetToken();

        // (
        Expect(SyntaxKinds.LeftParenthesisToken);
        // Identifier | StringLiteral
        Identifier? value = null;
        if (TryParse(IdentifierOrStringKinds, out _, allowNewLine: true))
        {
            value = ParseIdentifierLike();
            if (!EffectiveElementTypes.Any(e =>
                    e.Equals(value.Text, StringComparison.OrdinalIgnoreCase)))
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, value,
                    string.Join(" 或 ", EffectiveElementTypes));
            }
        }

        // )
        Expect(SyntaxKinds.RightParenthesisToken);

        MetadataElementType node = NodeFactory.CreateMetadataElementType(null, elementTypeKeywordToken, value);
        return FinishNode(node, GetStartPoint(elementTypeKeywordToken));
    }


    private void ParseMetadataCategorySuffixes(MetadataCategory category)
    {
        // tokens
        SyntaxToken? exclusiveKeywordToken = null;
        SyntaxToken? dkKeywordToken = null;
        SyntaxToken? refKeywordToken = null;
        SyntaxToken? naKeywordToken = null;
        SyntaxToken? fixKeywordToken = null;
        SyntaxToken? noFilterKeywordToken = null;

        while (!Eof())
        {
            if (!TryParse(MetadataCategoryEffectiveSuffixToken, out SourceNode? current,
                    allowNewLine: true))
            {
                break;
            }

            if (current.Kind == SyntaxKinds.OtherKeywordToken)
            {
                category.Update(ParseMetadataOther());
            }
            else if (current.Kind == SyntaxKinds.MultiplierKeywordToken)
            {
                category.Update(ParseMetadataMultiplier());
            }
            else if (current.Kind == SyntaxKinds.KeycodeKeywordToken)
            {
                category.Update(ParseMetadataKeyCode());
            }
            else if (current.Kind == SyntaxKinds.ExpressionKeywordToken)
            {
                category.Update(ParseMetadataExpression());
            }
            else if (current.Kind == SyntaxKinds.FactorKeywordToken)
            {
                category.Update(ParseMetadataFactor());
            }
            else if (current.Kind == SyntaxKinds.ElementTypeKeywordToken)
            {
                category.Update(ParseMetadataElementType());
            }
            else if (current.Kind == SyntaxKinds.ExclusiveKeywordToken)
            {
                exclusiveKeywordToken = GetToken();
            }
            else if (current.Kind == SyntaxKinds.DontKnowKeywordToken)
            {
                dkKeywordToken = GetToken();
            }
            else if (current.Kind == SyntaxKinds.RefuseKeywordToken)
            {
                refKeywordToken = GetToken();
            }
            else if (current.Kind == SyntaxKinds.NoAnswerKeywordToken)
            {
                naKeywordToken = GetToken();
            }
            else if (current.Kind == SyntaxKinds.FixKeywordToken)
            {
                fixKeywordToken = GetToken();
            }
            else if (current.Kind == SyntaxKinds.NoFilterKeywordToken)
            {
                noFilterKeywordToken = GetToken();
            }
            else
            {
                break;
            }
        }

        category.Update(dkKeywordToken, naKeywordToken, refKeywordToken, fixKeywordToken,
            noFilterKeywordToken, exclusiveKeywordToken);
    }


    /// <summary>
    ///     填充元数据脚本中的排序关键字。
    ///     此方法使用 <see cref="TryParse(SyntaxKinds[], out SourceNode, bool, bool)" /> 读取后续内容，不会影响后续读取。
    /// </summary>
    private void ParseMetadataOrder(IMetadataOrder metadataOrder)
    {
        while (TryParse(MetadataOrderKeywordTokens, out SourceNode? node, allowNewLine: true))
        {
            if (node.IsNode(SyntaxKinds.NamespaceKeywordToken))
            {
                if (metadataOrder.NamespaceKeywordToken != null)
                {
                    Raise(DiagnosticDescriptors.RepetitiveModifier);
                }
                else
                {
                    metadataOrder.Update(GetToken());
                }
            }
            else if (node.IsNode(SyntaxKinds.FixKeywordToken))
            {
                metadataOrder.Fix(GetToken());
            }
            else
            {
                metadataOrder.AddOrder(GetToken());
            }
        }
    }


    /// <summary>
    ///     列表引用元素后的sublist定义，需要当前节点是
    ///     <see cref="SyntaxKinds.SublistKeywordToken" />。
    /// </summary>
    private MetadataSubList ParseMetadataSubList()
    {
        SyntaxToken subListKeywordToken = GetToken();
        MetadataSubList subList = NodeFactory.CreateMetadataSubList(null, subListKeywordToken);
        return FinishNode(subList, GetStartPoint(subListKeywordToken));
    }


    /// <summary>
    ///     解析元数据列表引用语句，需要当前节点是 use 关键字。
    /// </summary>
    /// <remarks>
    ///     <code>
    ///         [.] use define_list [ sublist [ rot[ate] | ran | randomize | rev[erse] |
    ///         asc[ending] | desc[ending] ] ]
    ///     </code>
    /// </remarks>
    private MetadataListReference ParseMetadataListReference()
    {
        SyntaxToken? dotToken = null;
        SyntaxToken useKeywordToken;
        // . use...
        if (CurrentIs(SyntaxKinds.DotToken))
        {
            dotToken = GetToken();
            useKeywordToken = Expect(SyntaxKinds.UseKeywordToken);
        }
        else
        {
            useKeywordToken = GetToken();
        }

        SyntaxToken? topLevelToken = null;
        MetadataSubList? subList = null;

        TryParse(SyntaxKinds.BackSlashBackSlashDotToken,
            () => topLevelToken = GetToken(),
            allowNewLine: true);

        Identifier listName = Identifier.Default;
        if (TryParse(IdentifierOrStringKinds, out _, allowNewLine: true))
        {
            listName = ParseIdentifierLike();
        }

        // sublist
        if (TryParse(SyntaxKinds.SublistKeywordToken, allowNewLine: true))
        {
            subList = ParseMetadataSubList();
        }

        MetadataListReference reference = NodeFactory.CreateMetadataListReference(null, dotToken, useKeywordToken,
            listName, topLevelToken, subList);
        // label
        ParseMetadataLabeledInfo().UpdateToLabeledObject(reference);
        // order
        ParseMetadataOrder(reference);

        return FinishNode(reference, GetStartPoint(useKeywordToken));
    }


    /// <summary>
    ///     解析单个分类值定义，需要当前节点是 <see cref="SyntaxKinds.Identifier" /> 或
    ///     <see cref="SyntaxKinds.String" />
    /// </summary>
    private MetadataCategory ParseMetadataCategory()
    {
        SourceNode current = GetCurrentNode();
        SyntaxPoint start = GetCurrentStartPoint();
        Identifier id = Identifier.Default;

        // id | Keyword | string
        if (current.IsIdentifier || current.IsString ||
            (current.IsKeywordToken() &&
             !current.IsNode(SyntaxKinds.UseKeywordToken)))
        {
            id = ParseMetadataNameIdOrString();
        }

        MetadataCategory category = NodeFactory.CreateMetadataCategory(null, id);

        // use | .
        if (CurrentIsOneOf(SyntaxKinds.UseKeywordToken, SyntaxKinds.DotToken) ||
            TryParse([SyntaxKinds.UseKeywordToken, SyntaxKinds.DotToken], out _, allowNewLine: true))
        {
            category.Update(ParseMetadataListReference());
        }
        else
        {
            ParseMetadataLabeledInfo().UpdateToLabeledObject(category);
        }

        ParseMetadataCategorySuffixes(category);

        // {
        TryParse(SyntaxKinds.LeftCurlyToken,
            () => category.Update(ParseMetadataCategories()),
            allowNewLine: true);

        // 节点无效时，返回一个空节点。空节点在添加到集合中时会被忽略。
        if (!id.IsInvalid)
        {
            FinishNode(category, start);
        }

        return category;
    }


    /// <summary>
    ///     解析元数据分类列表，以左花括号 '{' 开始，右花括号 '}' 结束。
    ///     需要当前节点是左花括号 '{' <see cref="SyntaxKinds.LeftCurlyToken" />
    /// </summary>
    private MetadataCategories ParseMetadataCategories()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        MetadataCategories categories = NodeFactory.CreateMetadataCategories(null, null);
        // {
        SyntaxToken leftCurly = GetToken();
        ParseBlockWithSeparator([SyntaxKinds.RightCurlyToken], SyntaxKinds.CommaToken,
            ParseMetadataCategory, categories.Add, allowSeparatorNewline: true);
        SyntaxToken rightCurly = CurrentIs(SyntaxKinds.RightCurlyToken) ? GetToken() : SyntaxToken.Default;
        categories.Update(leftCurly, rightCurly);
        ParseMetadataOrder(categories);
        return FinishNode(categories, start);
    }


    /// <summary>
    ///     读取元数据值区间表达式，需要当前节点是','<see cref="SyntaxKinds.CommaToken" />
    ///     或'['<see cref="SyntaxKinds.LeftBracketToken" />。
    /// </summary>
    private MetadataFieldValueRange ParseMetadataFieldValueRange()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        Expression? lb = null;
        Expression? rb = null;
        SyntaxToken? caret = null;
        SyntaxToken? dotDot = null;
        SyntaxToken? stepKeywordToken = null;
        Expression? stepValue = null;

        // ^
        if (CurrentIs(SyntaxKinds.CaretToken))
        {
            caret = GetToken();
            Next();
        }

        // lb
        if (CurrentIsOneOf(MetadataFieldValueBoundKinds))
        {
            lb = ParseExpressionFromCurrent(allowAssignment: false);
            // DotDot
            if (TryParse(SyntaxKinds.DotDotToken, out SourceNode? dotDotNode, allowNewLine: true))
            {
                dotDot = NodeFactory.CreateSyntaxToken(dotDotNode);
                // rb
                if (TryParse(MetadataFieldValueBoundKinds, out _))
                {
                    rb = ParseExpressionFromCurrent();
                }
            }

            // step
            if (TryParse(SyntaxKinds.StepKeywordToken))
            {
                stepKeywordToken = GetToken();
                if (TryParse(MetadataFieldValueBoundKinds, out _))
                {
                    stepValue = ParseExpressionFromCurrent();
                }
            }
        }


        MetadataFieldValueRange range = NodeFactory.CreateMetadataFieldValueRange(
            null, caret, lb, dotDot, rb);
        range.StepKeywordToken = stepKeywordToken;
        range.StepValue = stepValue;
        return FinishNode(range, start);
    }


    /// <summary>
    ///     读取字段值区间表达式列表，需要当前节点是'['<see cref="SyntaxKinds.LeftBracketToken" />
    /// </summary>
    private MetadataFieldValueRangeList ParseMetadataFieldValueRangeList()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        SyntaxToken lb = GetToken();
        SyntaxToken? rb = null;
        List<MetadataFieldValueRange> ranges = new();

        ParseBlockWithSeparator([SyntaxKinds.RightBracketToken], SyntaxKinds.CommaToken,
            ParseMetadataFieldValueRange, ranges.Add, true, true);

        if (CurrentIs(SyntaxKinds.RightBracketToken))
        {
            rb = GetToken();
        }

        MetadataFieldValueRangeList list = NodeFactory.CreateMetadataFieldValueRangeList(
            null, lb, rb, ranges);
        return FinishNode(list, start);
    }

    // db
    // (
    //         ConnectionString = "connection_string_value",
    //         Table = "table_value",
    //         [MinAnswers = min_answers_value]
    //         [MaxAnswers = max_answers_value]
    //         [SQLFilter = sqlFilter_string]
    //         [CacheTimeout = cache_timeout_value]
    //         Columns
    //         (
    //              ID = "id_column_name",
    //              Label = "label_column_name"
    //              [KeyCode = "keycode_column_name"]
    //              [File = "file_column_name"]
    //              [AnalysisValue = "analysis_value_column_name"]
    //              [Fixed = "fixed_column_name"]
    //              [Exclusive = "exclusive_column_name"]
    //         )
    // )


    /// <summary>
    ///     解析数据库字段定义属性中的 Columns 属性定义。需要当前节点是'Columns'
    /// </summary>
    private MetadataDbColumns ParseMetadataDbColumns()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        Identifier name = ParseIdentifierName();
        List<MetadataProperty> props = new();
        // (
        Expect(SyntaxKinds.LeftParenthesisToken, true);
        ParseBlockWithSeparator([SyntaxKinds.RightParenthesisToken], SyntaxKinds.CommaToken,
            ParseMetadataProperty, props.Add, false, true);

        MetadataDbColumns columns = NodeFactory.CreateMetadataDbColumns(null, name, props);
        return FinishNode(columns, start);
    }


    /// <summary>
    ///     解析数据库字段定义属性。需要当前节点是'db'<see cref="SyntaxKinds.DbKeywordToken" />
    /// </summary>
    /// <returns></returns>
    private MetadataDbProperties ParseMetadataDbProperties()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        SyntaxToken dbKw = GetToken();
        List<MetadataProperty> props = new();
        MetadataDbColumns? columns = null;
        // (
        Expect(SyntaxKinds.LeftParenthesisToken, true);
        ParseBlockWithSeparator(
            [SyntaxKinds.RightParenthesisToken],
            SyntaxKinds.CommaToken,
            () =>
            {
                SourceNode current = GetCurrentNode();
                if (current.IsIdentifier &&
                    string.Equals(current.Text, "columns", StringComparison.OrdinalIgnoreCase))
                {
                    columns = ParseMetadataDbColumns();
                    return NodeFactory.CreateMetadataProperty(null, Identifier.Default, null);
                }

                return ParseMetadataProperty();
            },
            p =>
            {
                if (!Identifier.IsDefaultOrEmpty(p.NameIdentifier))
                {
                    props.Add(p);
                }
            },
            allowSeparatorNewline: true);

        MetadataDbProperties dbProps = NodeFactory.CreateMetadataDbProperties(null, dbKw, columns, props);
        return FinishNode(dbProps, start);
    }


    /// <summary>
    ///     解析字段列表，( field (; field )* [;] )，
    ///     需要当前节点是'fields' <see cref="SyntaxKinds.FieldsKeywordToken" />。
    /// </summary>
    private MetadataClass ParseMetadataClass()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        SyntaxToken fieldsKw = GetToken();
        List<MetadataField> fields = new();
        MetadataLabeledObjectStartInfo info = StartMetadataLabeledObject();
        // (
        if (!SyntaxToken.IsNullOrEmpty(Expect(SyntaxKinds.LeftParenthesisToken, true)))
        {
            ParseBlockWithSeparator([SyntaxKinds.RightParenthesisToken],
                SyntaxKinds.SemicolonToken,
                () => ParseMetadataField(),
                fields.Add, true, true);
        }

        MetadataClass mtClass = NodeFactory.CreateMetadataClass(null, fieldsKw, fields);
        info.LabeledObjectInfo.UpdateToLabeledObject(mtClass);
        return FinishNode(mtClass, start);
    }


    /// <summary>
    ///     解析字段后缀轴表达式 axis("Expression")，需要当前节点是
    ///     <see cref="SyntaxKinds.AxisKeywordToken" />
    /// </summary>
    private MetadataAxis ParseMetadataAxis()
    {
        SyntaxToken axisKeyword = GetToken();
        StringLiteral? expr = null;
        // (
        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            SyntaxToken strToken = Expect(SyntaxKinds.String, true);
            if (!SyntaxToken.IsNullOrEmpty(strToken))
            {
                expr = NodeConverter.ToString(strToken);
            }

            Expect(SyntaxKinds.RightParenthesisToken, true);
        }

        MetadataAxis axis = NodeFactory.CreateMetadataAxis(null, axisKeyword, expr);
        return FinishNode(axis, GetStartPoint(axisKeyword));
    }


    /// <summary>
    ///     解析字段后缀用法类型表达式 usageType("T1,T2,T3...") 或 usageType(T1,T2,...)
    ///     此处不检查其中内容是否正确。需要当前节点是<see cref="SyntaxKinds.UsageTypeKeywordToken" />
    /// </summary>
    private MetadataUsageType ParseMetadataUsageType()
    {
        SyntaxToken usageTypeKeyword = GetToken();
        StringLiteral? expr = null;
        // (
        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            expr = ParseContinuousTokenAsString(SyntaxKinds.RightParenthesisToken);
            Expect(SyntaxKinds.RightParenthesisToken, true);
        }

        MetadataUsageType usageType = NodeFactory.CreateMetadataUsageType(null, usageTypeKeyword, expr);
        return FinishNode(usageType, GetStartPoint(usageTypeKeyword));
    }


    /// <summary>
    ///     解析 InitialAnswer 或 DefaultAnswer，需要当前是
    ///     <see cref="SyntaxKinds.InitialAnswerKeywordToken" />或
    ///     <see cref="SyntaxKinds.DefaultAnswerKeywordToken" />
    /// </summary>
    private T ParseMetadataInitialAnswerOrDefaultAnswer<T>(
        Func<SyntaxNode?, SyntaxToken, Expression?, T> creator)
        where T : SyntaxNode
    {
        SyntaxToken keyword = GetToken();
        Expression? expr = null;
        // (
        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            expr = ParseExpression();
            Expect(SyntaxKinds.RightParenthesisToken, true);
        }

        T res = creator(null, keyword, expr);
        return FinishNode(res, GetStartPoint(keyword));
    }


    /// <summary>
    ///     解析字段后缀precision表达式，需要当前是<see cref="SyntaxKinds.PrecisionKeywordToken" />
    /// </summary>
    private MetadataPrecision ParseMetadataPrecision()
    {
        SyntaxToken precisionKeywordToken = GetToken();
        Expression? value = null;

        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true) &&
            !TryParse(SyntaxKinds.RightParenthesisToken, allowNewLine: true))
        {
            value = ParseExpression();
            Expect(SyntaxKinds.RightParenthesisToken);
        }

        MetadataPrecision precision = NodeFactory.CreateMetadataPrecision(null,
            precisionKeywordToken, value);
        return FinishNode(precision, GetStartPoint(precisionKeywordToken));
    }


    /// <summary>
    ///     解析字段后缀scale表达式，需要当前是<see cref="SyntaxKinds.ScaleKeywordToken" />
    /// </summary>
    private MetadataScale ParseMetadataScale()
    {
        SyntaxToken scaleKeywordToken = GetToken();
        Expression? value = null;

        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true) &&
            !TryParse(SyntaxKinds.RightParenthesisToken, allowNewLine: true))
        {
            value = ParseExpression();
            Expect(SyntaxKinds.RightParenthesisToken);
        }

        MetadataScale scale = NodeFactory.CreateMetadataScale(null,
            scaleKeywordToken, value);
        return FinishNode(scale, GetStartPoint(scaleKeywordToken));
    }


    /// <summary>
    ///     解析字段后缀 helperFields 表达式，需要当前是<see cref="SyntaxKinds.HelperFieldsKeywordToken" />
    /// </summary>
    private MetadataHelperFields ParseMetadataHelperFields()
    {
        SyntaxToken helperFieldsKeywordToken = GetToken();
        MetadataHelperFields helperFields = NodeFactory.CreateMetadataHelperFields(null, helperFieldsKeywordToken);

        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            ParseBlockWithSeparator([SyntaxKinds.RightParenthesisToken],
                SyntaxKinds.SemicolonToken,
                () => ParseMetadataField(),
                helperFields.AddField,
                true, true);
        }

        return FinishNode(helperFields, GetStartPoint(helperFieldsKeywordToken));
    }


    /// <summary>
    ///     解析字段后缀 codes 表达式，需要当前是<see cref="SyntaxKinds.CodesKeywordToken" />
    /// </summary>
    private MetadataCodes ParseMetadataCodes()
    {
        SyntaxToken codesKeywordToken = GetToken();
        MetadataCategories? categories = null;
        MetadataFieldReference? fieldReference = null;

        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            // {
            if (TryParse(SyntaxKinds.LeftCurlyToken, allowNewLine: true))
            {
                categories = ParseMetadataCategories();
            }
            // use
            else if (TryParse(SyntaxKinds.UseKeywordToken, allowNewLine: true))
            {
                fieldReference = ParseMetadataFieldReference();
            }

            // )
            Expect(SyntaxKinds.RightParenthesisToken, true);
        }

        MetadataCodes codes = NodeFactory.CreateMetadataCodes(null,
            codesKeywordToken, categories);
        // use field
        if (fieldReference != null)
        {
            codes.Update(fieldReference);
        }

        return FinishNode(codes, GetStartPoint(codesKeywordToken));
    }


    /// <summary>
    ///     解析字段后缀 validation 表达式，需要当前是<see cref="SyntaxKinds.ValidationKeywordToken" />
    /// </summary>
    private MetadataValidation ParseMetadataValidation()
    {
        SyntaxToken validationKeywordToken = GetToken();
        StringLiteral? expr = null;

        if (TryParse(SyntaxKinds.LeftParenthesisToken, allowNewLine: true))
        {
            SyntaxToken exprToken = Expect(SyntaxKinds.String, true);
            if (!SyntaxToken.IsNullOrEmpty(exprToken))
            {
                expr = NodeConverter.ToString(exprToken);
            }

            Expect(SyntaxKinds.RightParenthesisToken, true);
        }

        MetadataValidation validation = NodeFactory.CreateMetadataValidation(null, validationKeywordToken, expr);
        return FinishNode(validation, GetStartPoint(validationKeywordToken));
    }


    private void ParseMetadataFieldSuffix(MetadataField field)
    {
        SyntaxToken? noCaseDataKeywordToken = null;
        SyntaxToken? unversionedKeywordToken = null;
        SyntaxToken? versionedKeywordToken = null;

        // Grid suffixes
        SyntaxToken? rowKeywordToken = null;
        SyntaxToken? columnKeywordToken = null;
        SyntaxToken? expandKeywordToken = null;
        SyntaxToken? gridKeywordToken = null;

        while (true)
        {
            if (!TryParse(FieldSuffixKeyword, out SourceNode? node, allowNewLine: true))
            {
                break;
            }

            switch (node.Kind)
            {
                //  expression ("expression_text"
                //      [, (derive elements | no derive elements ) ] )
                case SyntaxKinds.ExpressionKeywordToken:
                    field.Update(ParseMetadataExpression());
                    break;

                // axis ("expression_text")
                case SyntaxKinds.AxisKeywordToken:
                    field.Update(ParseMetadataAxis());
                    break;

                // usageType ("type1, type2, ...")
                case SyntaxKinds.UsageTypeKeywordToken:
                    field.Update(ParseMetadataUsageType());
                    break;

                // precision (number)
                case SyntaxKinds.PrecisionKeywordToken:
                    field.Update(ParseMetadataPrecision());
                    break;

                // scale (number)
                case SyntaxKinds.ScaleKeywordToken:
                    field.Update(ParseMetadataScale());
                    break;

                // initialAnswer ()
                case SyntaxKinds.InitialAnswerKeywordToken:
                    field.Update(ParseMetadataInitialAnswerOrDefaultAnswer(
                        NodeFactory.CreateMetadataInitialAnswer));
                    break;

                // defaultAnswer ()
                case SyntaxKinds.DefaultAnswerKeywordToken:
                    field.Update(ParseMetadataInitialAnswerOrDefaultAnswer(
                        NodeFactory.CreateMetadataDefaultAnswer));
                    break;

                // helperFields ()
                case SyntaxKinds.HelperFieldsKeywordToken:
                    field.Update(ParseMetadataHelperFields());
                    break;

                // codes ()
                case SyntaxKinds.CodesKeywordToken:
                    field.Update(ParseMetadataCodes());
                    break;

                // validation ()
                case SyntaxKinds.ValidationKeywordToken:
                    field.Update(ParseMetadataValidation());
                    break;

                // NoCaseData
                case SyntaxKinds.NoCaseDataKeywordToken:
                    noCaseDataKeywordToken = GetToken();
                    break;

                // Versioned
                case SyntaxKinds.VersionedKeywordToken:
                    versionedKeywordToken = GetToken();
                    break;

                // Unversioned
                case SyntaxKinds.UnversionedKeywordToken:
                    unversionedKeywordToken = GetToken();
                    break;

                // row
                case SyntaxKinds.RowKeywordToken:
                    rowKeywordToken = GetToken();
                    break;

                // column
                case SyntaxKinds.ColumnKeywordToken:
                    columnKeywordToken = GetToken();
                    break;

                // expand
                case SyntaxKinds.ExpandKeywordToken:
                    expandKeywordToken = GetToken();
                    break;

                // grid
                case SyntaxKinds.GridKeywordToken:
                    gridKeywordToken = GetToken();
                    break;

                default:
                    return;
            }
        }

        field.Update(noCaseDataKeywordToken, unversionedKeywordToken, versionedKeywordToken);
        field.Update(rowKeywordToken, columnKeywordToken, expandKeywordToken, gridKeywordToken);
    }


    /// <summary>
    ///     读取元数据字段定义，需要当前节点是字符串<see cref="SyntaxKinds.String" />或者
    ///     标识符<see cref="SyntaxKinds.Identifier" />或<paramref name="info" />不是<see langword="null" />。
    /// </summary>
    private MetadataField ParseMetadataField(MetadataLabeledObjectStartInfo? info = null)
    {
        info ??= StartMetadataLabeledObject();
        SyntaxToken declareKwToken = SyntaxToken.Default;

        // 字段类型定义关键字
        if (TryParse(MetadataFieldKindTokens, out _, allowNewLine: true))
        {
            declareKwToken = GetToken();
        }

        MetadataField field = NodeFactory.CreateMetadataField(null, info.Id,
            declareKwToken, null);
        info.LabeledObjectInfo.UpdateToLabeledObject(field);

        // page
        if (declareKwToken.IsNode(SyntaxKinds.PageKeywordToken))
        {
            Expect(SyntaxKinds.LeftParenthesisToken);
            ParseBlockWithSeparator([SyntaxKinds.RightParenthesisToken],
                SyntaxKinds.CommaToken, ParseIdentifierLike,
                id => field.Update(id), allowSeparatorNewline: true);
        }
        else
        {
            // [ -> 字段值区间
            TryParse(SyntaxKinds.LeftBracketToken,
                () => field.Update(ParseMetadataFieldValueRangeList()),
                allowNewLine: true);

            // db
            TryParse(SyntaxKinds.DbKeywordToken,
                () => field.Update(ParseMetadataDbProperties()),
                allowNewLine: true);

            // { -> 分类列表
            TryParse(SyntaxKinds.LeftCurlyToken,
                () => field.Update(ParseMetadataCategories()),
                allowNewLine: true);

            // fields
            TryParse(SyntaxKinds.FieldsKeywordToken,
                () => field.Update(ParseMetadataClass()),
                allowNewLine: true);

            ParseMetadataFieldSuffix(field);
        }

        if (!Identifier.IsDefaultOrEmpty(info.Id))
        {
            FinishNode(field, GetStartPoint(info.Id));
        }

        return field;
    }


    /// <summary>
    ///     读取元数据语句块，读取字段定义<see cref="MetadataField" />或
    ///     区域语言定义<see cref="MetadataArealDeclaration" />。
    ///     需要当前节点是<see cref="StringLiteral" />或<see cref="Identifier" />
    /// </summary>
    private Statement ParseMetadataStatement()
    {
        MetadataLabeledObjectStartInfo labeledInfo = StartMetadataLabeledObject();
        Statement stat;

        if (TryParse(SyntaxKinds.LclKeywordToken, allowNewLine: true))
        {
            stat = ParseMetadataArealDeclaration(labeledInfo);
        }
        else
        {
            stat = ParseMetadataField(labeledInfo);
        }

        Expect(SyntaxKinds.SemicolonToken);
        return stat;
    }


    private record MetadataLabeledObjectInfo
    {
        public static readonly MetadataLabeledObjectInfo Empty = new()
        {
            Properties = new List<MetadataProperties>(),
            Templates = new List<MetadataTemplates>(),
            Styles = new List<MetadataStyle>(),
            LabelStyles = new List<MetadataStyle>(),
            Labels = new List<MetadataLabel>()
        };

        /// <summary>
        ///     属性列表
        /// </summary>
        public required List<MetadataProperties> Properties { get; init; }

        /// <summary>
        ///     模板属性列表
        /// </summary>
        public required List<MetadataTemplates> Templates { get; init; }

        /// <summary>
        ///     样式属性列表
        /// </summary>
        public required List<MetadataStyle> Styles { get; init; }

        /// <summary>
        ///     标签样式列表
        /// </summary>
        public required List<MetadataStyle> LabelStyles { get; init; }

        /// <summary>
        ///     字符串描述列表
        /// </summary>
        public required List<MetadataLabel> Labels { get; init; }


        public void UpdateToLabeledObject(MetadataLabeledObject obj)
        {
            Properties.ForEach(obj.AddProperties);
            Templates.ForEach(obj.AddTemplates);
            Styles.ForEach(obj.AddStyle);
            LabelStyles.ForEach(obj.AddLabelStyle);
            Labels.ForEach(obj.AddLabel);
        }
    }


    private readonly struct MetadataArealInfo(
        StringLiteral? language,
        StringLiteral? userContext,
        StringLiteral? labelType)
    {
        public StringLiteral? Language { get; } = language;
        public StringLiteral? UserContext { get; } = userContext;
        public StringLiteral? LabelType { get; } = labelType;
    }

    private record MetadataLabeledObjectStartInfo
    {
        public required Identifier Id { get; init; }
        public required MetadataLabeledObjectInfo LabeledObjectInfo { get; init; }
    }
}